package gspushmq.v1.app.subscribeapp.api;
import static gspushmq.v1.app.subscribeapp.config.Config.APP_KEY_ANDORID;
import static gspushmq.v1.app.subscribeapp.config.Config.APP_KEY_IOS;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import com.google.common.collect.Lists;

import ggframework.mongodb.BasicDBObject;
import ggframework.mongodb.DBCollection;
import ggframework.mongodb.DBObject;
import ggframework.util.GGLogger;
import gspushmq.v1.app.subscribeapp.enumeration.ConsumerEnum;
import gspushmq.v1.app.subscribeapp.enumeration.LogicEnum;
import gspushmq.v1.app.subscribeapp.enumeration.MsgStatusEnum;
import gspushmq.v1.app.subscribeapp.enumeration.ProducerEnum;
import gspushmq.v1.app.subscribeapp.enumeration.TagNoPushEnum;
import gspushmq.v1.app.subscribeapp.enumeration.TargetEnum;
import gspushmq.v1.app.subscribeapp.models.AndroidMessge;
import gspushmq.v1.app.subscribeapp.models.BaseVO;
import gspushmq.v1.app.subscribeapp.models.IOSMessge;
import gspushmq.v1.app.subscribeapp.models.LocalDO;
import gspushmq.v1.app.subscribeapp.models.Message;
import gspushmq.v1.app.subscribeapp.utils.AliPushHelper;
import gspushmq.v1.app.subscribeapp.utils.LocalSerialHelper;
import gspushmq.v1.app.subscribeapp.utils.ValidateHelper;


/**
 * @Description 推送接口
 * <p>
 * 集成aliyun移动推送平台
 * @Author chengsj
 * @Date 2018/9/11 17:30
 * @Version 1.0
 * @company 上海朝阳永续信息技术有限公司
 * @copyright (c) 2015 SunTime Co'Ltd Inc. All rights reserved.
 **/

public class PushHelper {


    /**
     * @Description 取消推送至app
     * @Author chengsj
     * @Version 1.0
     */
    public static void cancel(Long id) throws Exception {

        DBCollection collection = gspushmq.util.MongoUtil.getFtMixCollection("cs_msg_app_content");
        DBObject o = collection.findOne(new BasicDBObject("id",id).append("status",LogicEnum.EXIT.getCode()));
        if (o == null)
            throw new Exception("本地消息获取异常!");
        Long appKey = null;
        if (o.getString("consumer") !=null){
            if (o.getString("consumer").contains("iOS"))
                appKey = APP_KEY_IOS;
            if (o.getString("consumer").contains("安卓"))
                appKey = APP_KEY_ANDORID;
        }
        if (appKey == null)
            throw new Exception("appKey获取异常!");
        if (o.getLong("sid") == null)
            throw new Exception("阿里消息sid获取异常!");
        // 取消阿里定时任务
        AliPushHelper.cancelPush(o.getLong("sid"),appKey);
        // 同步本地数据库
        LocalSerialHelper.delLocal(id);
    }

    /**
     *
     * @Description 推送消息/通知给app
     * @Author chengsj
     * @Version 1.0
     * @param
     *
     */
    public static void pushApp(BaseVO vo) throws Exception{
        if (vo == null) throw new Exception("推送消息对象不能为null");
        LocalDO localDO = new LocalDO(vo);
        ValidateHelper.validate(vo);
        if (getDevice(vo.getConsumer_code()).contains(ConsumerEnum.iOS.getCode())) {
            IOSMessge messge = new IOSMessge();
            push(messge,localDO);
        }
        if (getDevice(vo.getConsumer_code()).contains(ConsumerEnum.Android.getCode())) {
            AndroidMessge messge = new AndroidMessge();
            push(messge,localDO);
        }
    }




    private static void push(Message messge,LocalDO localDO) throws Exception{
        messge.setTarget(localDO.getTarget());
        messge.setTargetValue(localDO.getTarget_value());
        messge.setTitle(localDO.getMessage_title());
        messge.setBody(localDO.getMessage_content());
        String parameters = "{\n" +
                "  \"notice_link_type\":  \""+localDO.getNotice_link_type()+"\",\n" +
                "  \"notice_goto_name\": \""+localDO.getNotice_goto_name()+"\",\n" +
                "  \"notice_goto_url\": \""+localDO.getNotice_goto_url()+"\",\n" +
                "  \"notice_goto_id\": \""+localDO.getNotice_goto_id()+"\",\n" +
                "  \"notice_ext_parameters\": \""+ localDO.getNotice_ext_parameters() +"\",\n" +
                "  \"notice_producer\": \""+ localDO.getProducer_code() +"\"\n" +
                "}";
        messge.setExtParameters(parameters);
        if (messge instanceof AndroidMessge) {
            messge.setAppKey(APP_KEY_ANDORID);
            messge.setDeviceType(ConsumerEnum.Android.getChannel());
            localDO.setConsumer(ConsumerEnum.Android.getName());
            localDO.setConsumer_code(ConsumerEnum.Android.getCode());
        }
        if (messge instanceof IOSMessge) {
            messge.setAppKey(APP_KEY_IOS);
            messge.setDeviceType(ConsumerEnum.iOS.getChannel());
            localDO.setConsumer(ConsumerEnum.iOS.getName());
            localDO.setConsumer_code(ConsumerEnum.iOS.getCode());
        }
        if (TargetEnum.ACCOUNT.getKey().equals(localDO.getTarget())){
            //target_value,如果是账户推送，则过滤相关账号
            String push_target_value = removeNoReciveMessageAccount(localDO.getProducer_code(),localDO.getLevels()
                    ,messge.getAppKey(),localDO.getTarget());
            if (StringUtils.isBlank(push_target_value)){
                GGLogger.warn(PushHelper.class,messge.getDeviceType()+"target_value过滤后为空！");
                return;
            }
            messge.setTargetValue(push_target_value);
            //同步本地数据库targetValue
            localDO.setTarget_value(push_target_value);
        }
        Date start_time = localDO.getStart_time();
        if (start_time == null)
            start_time = new Date();
        messge.setPushDate(start_time);

        Date end_time = localDO.getEnd_time();
        //设置离线消息保存时间，时间戳
        if (start_time != null && end_time !=null && start_time.compareTo(end_time) < 0){
            messge.setExpireTime(end_time.getTime() - start_time.getTime());
        }

        String suid = AliPushHelper.advancedPush(messge);
        if (StringUtils.isBlank(suid)) { //投递mongodb
            throw new Exception("通知投递阿里云失败！");
        }
        localDO.setSid(suid);
        localDO.setPush_time(new Date());
        localDO.setPush_status(MsgStatusEnum.HAS_PUSH_THIRD.getStatus());
        localDO.setPush_status_name(MsgStatusEnum.HAS_PUSH_THIRD.getStatusName());
        LocalSerialHelper.pushToLocal(localDO);
    }
    private static  List<Integer> getDevice(Integer consumer_code){
        List<Integer> list = Lists.newArrayList();
        if (consumer_code == null){
            list.add(ConsumerEnum.iOS.getCode());
            list.add(ConsumerEnum.Android.getCode());
        }else if (ConsumerEnum.iOS.getCode() == consumer_code) {
            list.add(ConsumerEnum.iOS.getCode());
        }else if (ConsumerEnum.Android.getCode() == consumer_code ) {
            list.add(ConsumerEnum.Android.getCode());
        }
        return list;
    }

    /**
     *
     * @Description 去除不接受相关消息的账户
     * @Author chengsj
     * @Version 1.0
     *
     */
    private static String removeNoReciveMessageAccount(Integer producer,String levels,Long appKey, String keyType) throws Exception{
        if (StringUtils.isBlank(levels))
            return null;
        String[] accounts = levels.split(",");
        List<String> allAccoutsList = new ArrayList<>(Arrays.asList(accounts));
        if (allAccoutsList == null)
            return null;
        List<String> accountsList = Lists.newArrayList();
        for (int i = 0; i< accounts.length ; i++){
            Set<String> tags = null;
            try {
                tags = AliPushHelper.queryTag(appKey, keyType, accounts[i]);
            }catch (Exception e){
                e.printStackTrace();
                GGLogger.warn(AliPushHelper.class,"查询tag列表失败：账户："+accounts[i]);
                continue;
            }
            if (tags == null || tags.size() == 0){
                accountsList.add(accounts[i]);
                GGLogger.warn(AliPushHelper.class,"用户未绑定tag，暂不推送！账户："+accounts[i]);
                continue;//没有tag，不推送
            }
            if (ProducerEnum.GG_Live.getCode() == producer){
                if (tags.contains(TagNoPushEnum.NO_LIVEREMINDER.getTag())){
                    accountsList.add(accounts[i]);
                }
            }else if (ProducerEnum.GG_OWNSTOCK.getCode() == producer){
                if (tags.contains(TagNoPushEnum.NO_OWNCHOOSECHANGE.getTag())){
                    accountsList.add(accounts[i]);
                }
            }else if (ProducerEnum.GG_BACK.getCode() == producer){
                if (tags.contains(TagNoPushEnum.NO_ASSISTANT.getTag())){
                    accountsList.add(accounts[i]);
                }
            }
        }
        allAccoutsList.removeAll(accountsList);
        StringBuffer buffer = new StringBuffer();
        for (String  s:allAccoutsList) {
            buffer.append(s).append(",");
        }
        String res = buffer.toString().trim();

        return res.length()>1 ? res.substring(0,res.length() - 1) : res;
    }


}
